/*
 * Communication.h
 *
 *  Created on: Apr 22, 2011
 *      Author: tflanzer
 */

#ifndef COMMUNICATION_H_
#define COMMUNICATION_H_

#include <cstdio>
#include <list>
#include "mavlink.h"
#include "timer.h"
#include "execStruct.h"
#include "FileWriter.h"

#define ACC_DEVICE 0x18
#define MAG_DEVICE 0x1E
#define LAT2METER 111194.93

class Communication: public Timer::fiveHzListener, public Timer::oneHzListener {
public:

	double tIMU[2], tGPS[2];
	int system_type, autopilot_type, numi, numg, nums, gndmsgtype;
	bool chksum_flag;
	uint8_t MAVLINK_MODE;
	bool imuin, gpsin, servoin, datInitReceived, imuDatReceived, runEKF;
	double initLat, initLon, initAlt;
	double lon2meter;
	double waypointLatDeg[50];
	double waypointLonDeg[50];

	Communication(Timer &timer, FileWriter *fw);
	virtual ~Communication();

	void oneHzUpdate(Timer &timer);
	void fiveHzUpdate(Timer &timer);

	// Port to ground station, autopilot, i2c
	int fgnd, faup, fi2c;

	class AUPListener{
	public:
		virtual void AUPdataReceived(Communication &com)=0;
		virtual ~AUPListener() {}
	};

	void addListenerAUP(AUPListener *listener);
	void removeListenerAUP(AUPListener *listener);
	void notifyListenersAUP();

	class GNDListener{
	public:
		virtual void GNDdataReceived(Communication &com)=0;
		virtual ~GNDListener() {}
	};

	void addListenerGND(GNDListener *listener);
	void removeListenerGND(GNDListener *listener);
	void notifyListenersGND();

	void closeSerialPorts();

	FileWriter *fw;
	Timer timer;

	private:
		bool interrupt_AUP;
		bool interrupt_GND;
		list<AUPListener*> listenersAUP;
		list<GNDListener*> listenersGND;
		static void *startAUPThread(void *);
		static void *startGNDThread(void *);
		void startGNDLoop();
		void startAUPLoop();
		bool getAUPData();
		bool getGNDData();
		int initializei2c();
		int16_t read_reg_acc(int fh, uint8_t reg, int count);
		int16_t read_reg_mag(int fh, uint8_t reg, int count);
		int write_reg(int fh, uint8_t reg, uint8_t val);
		void returnParams();
		void unpackWaypointInfo(const mavlink_message_t* msg);
		void updateIMUFile();
		void updateGPSFile();
};

#endif /* COMMUNICATION_H_ */
